今天我們要繼續進行"錯誤"囉
我們今天要來設計錯誤的Domain type,意思是發生錯誤時,會歸類於哪一種錯誤,好像有點繞口XD
假設我們開一間餐廳,那麼會有幾種錯誤呢?
這樣做我們可以歸類這些錯誤,當我們看到這些錯誤時,就可以做特別的處理,比如說遇到食材不足,那就進貨,或是不賣那道菜,最慘就是提早打烊囉XD
package model
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import org.springframework.http.ResponseEntity
sealed class MyError : Error() {
@Serializable
sealed class ValidateError : MyError()
@Serializable
sealed class ServerError : MyError()
@Serializable
data class ContainInfoError(val containInfo: String) : ValidateError()
@Serializable
data class DBConnectError(@Contextual val e: Error) : ServerError()
@Serializable
data class JsonEncodeError(@Contextual val e: Error) : ServerError()
@Serializable
data class CustomerNotFoundError(val customerId: String) : MyError()
companion object {
fun errorToResonse(myError: MyError): ResponseEntity<String> {
return when (myError) {
is DBConnectError ->
ResponseEntity.status(500).body("DB Connect Error: ${myError.e}")
is JsonEncodeError ->
ResponseEntity.status(500).body("Json Encoder Error: ${myError.e}")
is ContainInfoError ->
ResponseEntity.status(400).body("validation Error: ${myError.containInfo}")
is CustomerNotFoundError ->
ResponseEntity.status(404).body("ID: ${myError.customerId} Not Found!")
}
}
}
}
package controller
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import model.*
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
fun customerVOToCustomer(customerVO: CustomerVO) =
when {
customerVO.contactInfo.contains("@") -> Customer(
Name(customerVO.name),
Email(customerVO.contactInfo),
Age(customerVO.age)
)
customerVO.contactInfo.length > 8 -> throw Error("contactInfo Too Long")
else -> Customer(Name(customerVO.name), Phone(customerVO.contactInfo), Age(customerVO.age))
}
@RestController
@SpringBootApplication
open class MyApplication {
private val customerList = mutableListOf<Customer>()
@GetMapping("/api/v1/customers")
fun getAllCustomers(): ResponseEntity<String> {
if (customerList.isEmpty())
return MyError.errorToResonse(MyError.CustomerNotFoundError(customerId = "all"))
try {
Json.encodeToString(customerList)
} catch (e: Error) {
return MyError.errorToResonse(MyError.JsonEncodeError(e))
}.let {
return ResponseEntity.ok(it)
}
}
@PostMapping("/api/v1/customers")
fun createCustomer(@RequestBody newCustomer: String): ResponseEntity<String> {
Json.decodeFromString<CustomerVO>(newCustomer).let {
try {
customerVOToCustomer(it)
} catch (e: Error) {
return MyError.errorToResonse(MyError.ContainInfoError(e.toString()))
}
}.let {
customerList.add(it)
it
}.let {
try {
Json.encodeToString(it)
} catch (e: Error) {
return MyError.errorToResonse(MyError.JsonEncodeError(e))
}
}.let {
return ResponseEntity.ok(it)
}
}
@PutMapping("/api/v1/customers")
fun updateCustomer(@RequestBody newCustomer: String): ResponseEntity<String> {
Json.decodeFromString<CustomerVO>(newCustomer).let {
customerVOToCustomer(it)
}.let { validatedCustomer ->
return when (val index = customerList.indexOfFirst { it.name == validatedCustomer.name }) {
-1 -> MyError.errorToResonse(MyError.CustomerNotFoundError(customerId = index.toString()))
else -> {
customerList.set(index, validatedCustomer)
ResponseEntity.ok("Modify success")
}
}
}
}
@DeleteMapping("/api/v1/customers")
fun DeleteCustomer(@RequestBody newCustomer: String): ResponseEntity<String> {
Json.decodeFromString<CustomerVO>(newCustomer).let {
customerVOToCustomer(it)
}.let { validatedCustomer ->
return when (val index = customerList.indexOfFirst { it.name == validatedCustomer.name }) {
-1 -> MyError.errorToResonse(MyError.CustomerNotFoundError(customerId = index.toString()))
else -> {
customerList.removeAt(index)
ResponseEntity.ok("Delete success")
}
}
}
}
}
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
我們今天將錯誤處理更進一步,定義出屬於我們自己的type,這樣看到錯誤時,可以比較快地知道該怎麼處理! 別人一看到我們的程式碼,也可以很快地知道發生了甚麼事情,例如看到CustomerNotFoundError,第一眼就會想到,一定是顧客在DB中找不到了,那為甚麼找不到呢?我們就可以透過訊息來描述,比如說以這個名字來搜尋,找不到任何顧客,經過這樣的撰寫,我們的錯誤會更能表達真正的意義。